package com.thrm.servicios;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.Key;
import com.opensymphony.xwork2.ActionContext;
import com.thrm.actions.ActionResponsable;
import com.thrm.dao.CandidatosDAO;
import com.thrm.dao.ConocimientoEnCandidatoDAO;
import com.thrm.dao.ConocimientoEnOfertaDAO;
import com.thrm.dao.CurriculumsDAO;
import com.thrm.dao.IdiomasencandidatosDAO;
import com.thrm.dao.IdiomasenofertasDAO;
import com.thrm.dao.InscripcionDAO;
import com.thrm.dao.OfertaDAO;
import com.thrm.domain.Candidato;
import com.thrm.domain.Conocimiento;
import com.thrm.domain.ConocimientoEnCandidato;
import com.thrm.domain.Curriculum;
import com.thrm.domain.Curso;
import com.thrm.domain.Empresa;
import com.thrm.domain.Experiencia;
import com.thrm.domain.Formacion;
import com.thrm.domain.Idioma;
import com.thrm.domain.IdiomaEnCandidato;
import com.thrm.domain.Inscripcion;
import com.thrm.domain.Oferta;
import com.thrm.domain.Responsable;

public class ServiciosGlobales {

	private ResponsablesServicios rs = null;
	private InscripcionDAO inscripcionDAO;
	private OfertaDAO ofertaDAO;
	private FormacionesServicios formacionesServicios = null;
	private CursosServicios cursosServicios;
	private ExperienciasServicios es = null;
	private IdiomasServicios is = null;
	private ConocimientosServicios cos = null;
	private IdiomasencandidatosDAO icd = new IdiomasencandidatosDAO();;
	private ConocimientoEnCandidatoDAO ccd = null;
	private IdiomasenofertasDAO iod = null;
	private ConocimientoEnOfertaDAO cod = null;
	private CandidatosDAO cd = new CandidatosDAO();
	private CurriculumsDAO cud = new CurriculumsDAO();

	private List<Idioma> listaIdiomas = null;
	private List<Conocimiento> listaConocimientos = null;
	private List<Curso> listaCursos = null;
	private Map session = null;
	private CandidatosServicios candidatosServicios;
	private ConocimientosServicios conocimientosServicios;
	private ResponsablesServicios responsableServicios;
	
	public static final String NIF_STRING_ASOCIATION = "TRWAGMYFPDXBNJZSQVHLCKE";	
	
//	static final Logger log = Logger.getLogger("ServiciosGlobales");

	private static final Log log = LogFactory.getLog(ActionResponsable.class);

	public String eliminarInscripcionCandidato(Candidato candidato, Oferta oferta) {
		String resultado = "ERROR";
		boolean existeInscripcion = comprobarExistenciaInscripcion(candidato, oferta);
		if (existeInscripcion) {
			
			Set<Inscripcion> inscripciones = oferta.getInscripciones();
			for (Inscripcion inscripcion : inscripciones) {
				if(inscripcion.getCandidatoId() == candidato.getKey().getId())
					inscripciones.remove(inscripcion);
			}
			getOfertaDAO().merge(oferta);
			
		}
		return resultado;
	}

//	public String aceptarCandidatura(Candidato candidato, Oferta oferta) {
//		String resultado = "ERROR";
//		boolean existeInscripcion = this.comprobarExistenciaInscripcion(candidato, oferta);
//		if (existeInscripcion) {
//			Inscripcion inscripcion = new Inscripcion();
//			inscripcion.setCandidatos(candidato);
//			inscripcion.setOfertas(oferta);
//			List<Inscripcion> listaInscripciones = id.findByExample(inscripcion);
//			Iterator<Inscripcion> it = listaInscripciones.iterator();
//			boolean salirBucle = false;
//			while (it.hasNext() && salirBucle == false) {
//				Inscripcion ins = it.next();
//				if (ins.getCandidatos() == candidato && ins.getOfertas() == oferta) {
//					ins.setEstado("Aceptada");
//					id.attachClean(ins);
//					id.merge(ins);
//					resultado = "SUCCESS";
//					salirBucle = true;
//				}
//			}
//		}
//		return resultado;
//	}

//	public String desestimarCandidatura(Candidato candidato, Oferta oferta) {
//		String resultado = "ERROR";
//		boolean existeInscripcion = this.comprobarExistenciaInscripcion(candidato, oferta);
//		if (existeInscripcion) {
//			Inscripcion inscripcion = new Inscripcion();
//			inscripcion.setCandidatos(candidato);
//			inscripcion.setOfertas(oferta);
//			List<Inscripcion> listaInscripciones = id.findByExample(inscripcion);
//			Iterator<Inscripcion> it = listaInscripciones.iterator();
//			boolean salirBucle = false;
//			while (it.hasNext() && salirBucle == false) {
//				Inscripcion ins = it.next();
//				if (ins.getCandidatos() == candidato && ins.getOfertas() == oferta) {
//					ins.setEstado("Desestimada");
//					id.attachClean(ins);
//					id.merge(ins);
//					resultado = "SUCCESS";
//					salirBucle = true;
//				}
//			}
//		}
//		return resultado;
//	}
//
	/**
	 *  Comprueba si existe la inscripcion para un candidato y una oferta dada 
	 */
	public boolean comprobarExistenciaInscripcion(Candidato candidato, Oferta oferta) {

		Set inscripciones = oferta.getInscripciones();
		Iterator it = inscripciones.iterator();
		while(it.hasNext()){
			Inscripcion inscripcion = (Inscripcion)it.next();
			if(inscripcion.getCandidatoId() == candidato.getKey().getId())
				return true;
		}
				
		return false;

//		List<Inscripcion> listaInscripciones = id.findByExample(inscripcion);
//		Iterator<Inscripcion> it = listaInscripciones.iterator();
//		while (it.hasNext() && resultado == false) {
//			Inscripcion ins = it.next();
//			if (ins.getCandidatos() == candidato && ins.getOfertas() == oferta) {
//				resultado = true;
//			}
//		}
//		return resultado;
	}

	/** Muestra las ofertas de la empresa a la que el responsable pertenece */
	public Set<Oferta> mostrarOfertasResponsable(Responsable responsable) {
		Empresa empresa = responsable.getEmpresa();
		Set<Oferta> ofertas = empresa.getOfertas();
		return ofertas;
	}

	public String crearFormacionCandidato(Formacion formacion, String contenidoFichero, Candidato candidato, String nombreCurso) {
		String resultado = "ERROR";
//		try {
			if (contenidoFichero != null) {
				Blob ficheroBlob = stringToBlob(contenidoFichero);
				formacion.setExpediente(ficheroBlob);
			}
//			Curso curso = cursosServicios.buscarCursoPorNombre(nombreCurso);
//			if (formacion != null && candidato != null && curso != null) {
				candidato.getFormaciones().add(formacion);
//				formacion.setCursos(curso);
				resultado = getFormacionesServicios().guardarFormacion(formacion);
//			}
		return resultado;
	}
	
	public Blob stringToBlob(String contenido) {
		
		InputStream inputStream = null;
		byte[] bytes = new byte[524288];
		Blob blob = null;
		
		try {
			inputStream = IOUtils.toInputStream(contenido, "ISO-8859-1");
			inputStream.read(bytes);
			blob = new Blob(bytes);
		} catch (IOException e) {
			log.error("Streaming failed", e);
		}
		return blob;
	}

	public String crearExperienciaCandidato(Experiencia experiencia, Candidato candidato) {
		String resultado = "ERROR";
		if (experiencia != null && candidato != null) {
//			experiencia.setCandidatos(candidato);
			candidato.getExperiencias().add(experiencia);
			resultado = getExperienciasServicios().guardarExperiencia(experiencia);
		}
		return resultado;
	}

	public String eliminarExperienciaCandidato(Candidato candidato, Key key) {
		
		Experiencia experiencia = ExperienciasServicios.getInstance().buscarExperienciaPorKey(key);
		candidato.getExperiencias().remove(experiencia);
		String resultado = getExperienciasServicios().eliminarExperiencia(experiencia);
		return resultado;
	}

	private ExperienciasServicios getExperienciasServicios() {
		return ExperienciasServicios.getInstance();
	}

	public String crearIdiomaCandidato(String nombreIdioma, IdiomaEnCandidato idiomaEnCandidato, Candidato candidato) {
		is = IdiomasServicios.getInstance();
//		Idioma i = is.buscarIdiomaPorNombre(nombreIdioma);
		Idioma i = new Idioma(nombreIdioma);
		idiomaEnCandidato.setIdioma(i);
		candidato.getIdiomasEnCandidato().add(idiomaEnCandidato);
//		idiomaEnCandidato.setCandidatos(candidato);
		icd.save(idiomaEnCandidato);
		return "SUCCESS";
	}

	public String eliminarIdiomaEnCandidatoByKey(Key key) {
		String resultado = "ERROR";
		icd = new IdiomasencandidatosDAO();
		IdiomaEnCandidato ic = icd.findByKey(key);
		if (ic != null) {
			icd.delete(ic);
			resultado = "SUCCESS";
		}
		return resultado;
	}

	public String crearConocimientoCandidato(String nombreConocimiento,
			ConocimientoEnCandidato conocimientoEnCandidato, Candidato candidato) {
//		Conocimientos c = cos.buscarConocimientoPorNombre(nombreConocimiento);
		Conocimiento conocimiento = new Conocimiento(nombreConocimiento);
		conocimientoEnCandidato.setConocimiento(conocimiento);
		candidato.getConocimientosEnCandidato().add(conocimientoEnCandidato);
		ccd = new ConocimientoEnCandidatoDAO();
		ccd.save(conocimientoEnCandidato);
		return "SUCCESS";
	}

	public String eliminarConocimientoEnCandidatoByKey(Key key) {
		String resultado = "ERROR";

		ccd = new ConocimientoEnCandidatoDAO();
		ConocimientoEnCandidato cc = ccd.findByKey(key);
		if (cc != null) {
			ccd.delete(cc);
			resultado = "SUCCESS";
		}
		return resultado;
	}

//	public String crearIdiomaOferta(String nombreIdioma, Idiomasenofertas idiomaenoferta, Oferta oferta) {
//		String resultado = "ERROR";
//		is = IdiomasServicios.getInstance();
//		Idioma i = is.buscarIdiomaPorNombre(nombreIdioma);
//		idiomaenoferta.setIdiomas(i);
//		idiomaenoferta.setOfertas(oferta);
//		iod = new IdiomasenofertasDAO();
//		iod.save(idiomaenoferta);
//		resultado = "SUCCESS";
//		return resultado;
//	}
//
//	public String eliminarIdiomaOferta(int identificador) {
//		String resultado = "ERROR";
//		iod = new IdiomasenofertasDAO();
//		Idiomasenofertas io = iod.findById(identificador);
//		if (io != null) {
//			iod.delete(io);
//			resultado = "SUCCESS";
//		}
//		return resultado;
//	}
//
//	public String crearConocimientoOferta(String nombreConocimiento, ConocimientosEnOfertas conocimientoenoferta,
//			Oferta oferta) {
//		String resultado = "ERROR";
//		cos = ConocimientosServicios.getInstance();
//		Conocimientos c = cos.buscarConocimientoPorNombre(nombreConocimiento);
//		conocimientoenoferta.setConocimientos(c);
//		conocimientoenoferta.setOfertas(oferta);
//		cod = new ConocimientoEnOfertaDAO();
//		cod.save(conocimientoenoferta);
//		resultado = "SUCCESS";
//		return resultado;
//	}
//
//	public String eliminarConocimientoOferta(int identificador) {
//		String resultado = "ERROR";
//		cod = new ConocimientoEnOfertaDAO();
//		ConocimientosEnOfertas co = cod.findById(identificador);
//		if (co != null) {
//			cod.delete(co);
//			resultado = "SUCCESS";
//		}
//		return resultado;
//	}

	public List<Curso> cargarCursos() {
		listaCursos = getCursosServicios().mostrarCursos();
		/*
		 * Iterator <Curso> i=cursos.iterator(); if(cursos.size()>0) {
		 * listaCursos=new ArrayList(); while(i.hasNext()) { Curso c= (Curso)
		 * i.next(); listaCursos.add(c.getTipo()); } }
		 */
		return listaCursos;
	}

	public List<Idioma> cargarIdiomas() {
		listaIdiomas = getIdiomasServicios().mostrarIdiomas();
		return listaIdiomas;
	}

	private IdiomasServicios getIdiomasServicios() {
		return IdiomasServicios.getInstance();
	}

	public List<Conocimiento> cargarConocimientos() {
		listaConocimientos = getConocimientosServicios().mostrarConocimientos();
		return listaConocimientos;
	}

	private ConocimientosServicios getConocimientosServicios() {
		return conocimientosServicios;
	}

	/** 
	 * Carga el candidato a partir del dni almacenado en la sesi�n
	 *  
	 * */
	public Candidato cargarCandidato() {
		Map session = ActionContext.getContext().getSession();
		Candidato candidato = null;
		if (session != null) {
			String dni = session.get("dniUsuario").toString();
			candidato = getCandidatosServicios().buscarCandidatoPorDni(dni);
		}
		return candidato;
	}

	/** Carga el responsable a partir del dni almacenado en la sesión */
	public Responsable cargarResponsable() {
		Map<String, Object> session = ActionContext.getContext().getSession();
		Responsable responsable = null;
		if (session != null) {
			String dni = session.get("dniUsuario").toString();
			responsable = getResponsableServicios().buscarResponsablePorDni(dni);
		}
		return responsable;
	}

	public Curriculum descargarCurriculum(Key key) {
		CurriculumsDAO cud = new CurriculumsDAO();
		Curriculum curriculum = cud.findByKey(key);
		return curriculum;
	}

	public String guardarCurriculum(String fichero, Candidato candidato, String idioma, String fileName, String contentType) {
		String resultado = "ERROR";
		Set<Curriculum> curriculums = candidato.getCurriculums();

		for (Curriculum curriculum : curriculums) {
			if(!curriculum.getIdioma().equals(idioma))
				return resultado;
		}
		
		Blob ficheroBlob = stringToBlob(fichero);
		Curriculum curriculum = new Curriculum(idioma, Calendar.getInstance().getTime(), ficheroBlob, fileName, contentType);
		curriculums.add(curriculum);
		cud.save(curriculum);
		resultado = "SUCCESS";
		return resultado;
	}

	public CandidatosServicios getCandidatosServicios() {
		return candidatosServicios;
	}
	
	public void setCandidatosServicios(CandidatosServicios candidatosServicios) {
		this.candidatosServicios = candidatosServicios;
	}

	public String eliminarCurriculum(Candidato candidato, Key key) {
		String resultado = "ERROR";
//		Set<Curriculum> curriculums = candidato.getCurriculums();
		
		Curriculum curriculum = cud.findByKey(key);
		cud.delete(curriculum);
		resultado = "SUCCESS";
		return resultado;
	}

	/**
	 * security could be enhanced here.
	 */
	public boolean comprobarLogin() {
		boolean resultado = false;
		session = ActionContext.getContext().getSession();
		if (session != null) {
			if ((session.get("logueado") != null) && (session.get("logueado").toString().equals("true"))
					&& (session.get("usuario") != null)) {
				resultado = true;
			}
		}
		return resultado;
	}
//
//	public boolean comprobarPermisosResponsable(Oferta oferta) {
//		boolean resultado = false;
//		session = ActionContext.getContext().getSession();
//		if (session != null) {
//			rs = ResponsablesServicios.getInstance();
//			Responsable responsable = rs.buscarResponsablePorNombre(session.get("usuario").toString());
//			if (responsable != null) {
//				if (responsable.getEmpresas() == oferta.getEmpresas()) {
//					resultado = true;
//				}
//			}
//		}
//		return resultado;
//	}

	public boolean comprobarDni(String dni) {
		boolean resultado = false;
		try {
			int longitud = dni.length();
			if (longitud <= 9 && longitud > 1) {
				String dniSinLetra = dni.substring(0, longitud - 1);
				char letra = dni.charAt(longitud - 1);
				Integer numero = Integer.parseInt(dniSinLetra);
				char letraCorrecta = NIF_STRING_ASOCIATION.charAt(numero % 23);
				if (letra == letraCorrecta)
					resultado = true;
				else
					log.info("letra correcta: " + letraCorrecta);
			}
		} catch (NumberFormatException excepcion) {
			excepcion.printStackTrace();
		}
		return resultado;
	}

	public InscripcionDAO getInscripcionDAO() {
		return inscripcionDAO;
	}

	public void setInscripcionDAO(InscripcionDAO inscripcionDAO) {
		this.inscripcionDAO = inscripcionDAO;
	}

	public OfertaDAO getOfertaDAO() {
		return ofertaDAO;
	}

	public void setOfertaDAO(OfertaDAO ofertaDAO) {
		this.ofertaDAO = ofertaDAO;
	}

	public void setConocimientosServicios(ConocimientosServicios conocimientosServicios) {
		this.conocimientosServicios = conocimientosServicios;
	}

	public CursosServicios getCursosServicios() {
		return cursosServicios;
	}

	public void setCursosServicios(CursosServicios cursosServicios) {
		this.cursosServicios = cursosServicios;
	}

	public ResponsablesServicios getResponsableServicios() {
		return responsableServicios;
	}

	public void setResponsableServicios(ResponsablesServicios responsableServicios) {
		this.responsableServicios = responsableServicios;
	}

	public FormacionesServicios getFormacionesServicios() {
		return formacionesServicios;
	}

	public void setFormacionesServicios(FormacionesServicios formacionesServicios) {
		this.formacionesServicios = formacionesServicios;
	}
	
	/*
	 * Eliminar inscripcion del sistema public String
	 * eliminarInscripcionCandidato(Candidato candidato, Oferta oferta) {
	 * String resultado="ERROR"; boolean
	 * existeInscripcion=this.comprobarExistenciaInscripcion(candidato, oferta);
	 * if(existeInscripcion) { Inscripcion inscripcion=new Inscripcion();
	 * inscripcion.setCandidatos(candidato); inscripcion.setOfertas(oferta);
	 * List <Inscripcion> listaInscripciones=id.findByExample(inscripcion);
	 * Iterator <Inscripcion> it=listaInscripciones.iterator(); boolean
	 * salirBucle=false; while(it.hasNext() && salirBucle==false) {
	 * Inscripcion ins=it.next(); if(ins.getCandidatos()==candidato &&
	 * ins.getOfertas()==oferta) { id.delete(ins); resultado="SUCCESS";
	 * salirBucle=true; } } } return resultado; }
	 */
}
